import subprocess
import shlex

from flask import jsonify, request, current_app
from flask.views import MethodView

from app.apis.v1 import api_v1
from app.models import Software
from app.extensions import db
from app.apis.v1.schemas import system_info, software_schema
from app.apis.v1.errors import api_abort


def get_data(key):
    if request.get_json():
        return request.get_json().get(key)
    return None


class SystemInformationAPI(MethodView):

    def get(self):
        return jsonify(system_info())


class SoftwareAPI(MethodView):

    def get(self):
        """
        获取软件列表
        :return:
        """
        q = request.args.get('q')
        if q:
            software = Software.query.filter(Software.name.like('%{}%'.format(q))).all()
            result = {}
            for each in software:
                if result.get(each.name):
                    result.get(each.name).append(software_schema(each))
                else:
                    result[each.name] = [software_schema(each)]
            return jsonify(result)
        name_column = Software.query.with_entities(Software.name).distinct().all()
        name_list = []
        for item in name_column:
            name_list.append(item.name)
        result = {}
        result = result.fromkeys(name_list)
        for each in result:
            software = Software.query.filter_by(name=each)
            result[each] = [software_schema(single_version) for single_version in software]
        return jsonify(result)

    def post(self):
        software_id = get_data('softwareId')
        software = Software.query.get_or_404(software_id)
        if software.status == 1:
            return jsonify({'code': 500, 'msg': '{} has benn installed already!'.format(software.name)})
        software.status = 2
        db.session.commit()
        install = subprocess.run(shlex.split('bash ./install.sh' + software.cmd.install), stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE, cwd=current_app.config['ONEINSTACK_PATH'])
        print(install.stdout)
        if install.returncode == 1:
            software.status = 0
            db.session.commit()
            return jsonify({'code': 500, 'msg': install.stdout})
        software.status = 1
        db.session.commit()
        return jsonify({'code': 200, 'msg': '{} has been installed successfully!'.format(software.name)})

    def delete(self):
        software_id = get_data('softwareId')
        software = Software.query.get_or_404(software_id)
        if software.status == 0:
            return jsonify({'code': 500, 'msg': '{} has not been installed'.format(software.name)})
        cmd = 'bash ./uninstall.sh ' + software.cmd.uninstall
        uninstall = subprocess.run(shlex.split(cmd), cwd=current_app.config['ONEINSTACK_PATH'], stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        if uninstall.returncode == 1:
            return jsonify({'code': 500, 'msg': 'Failed to uninstall!'})
        software.status = 0
        db.session.commit()
        return jsonify({'code': 200, 'msg': 'Successfully uninstalled nginx'})


api_v1.add_url_rule('/system_status', view_func=SystemInformationAPI.as_view('system'), methods=['GET'])
api_v1.add_url_rule('/software', view_func=SoftwareAPI.as_view('software'), methods=['GET', 'POST', 'DELETE'])

install = subprocess.run(shlex.split('bash ./uninstall.sh --web'), cwd='/www/fancy/FancyPanel/app/software/oneinstack')